package com.uwosh.cs342.g6.mapapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.android.gms.internal.z;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.VisibleRegion;
import com.google.gson.JsonObject;
import com.uwosh.cs342.g6.mapapp.R;

import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnMapClickListener, OnMapLongClickListener {

	
	final CharSequence[] types = {"Airport", "Bank/ATM","Bar","Car Repair","Medical","Food","Gas/Car Wash","Gym","Locksmith","Lodging","Attractions","Parks","Parking","Place Of Worship","Post Office","Store/Pharmacy"};
	final boolean[] states = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
	
	private final String SATELLITE = "Satellite";
	private final String MAP = "Map";
	private final String HYBRID = "Hybrid";
	
	final CharSequence[] mapTypes = {MAP, SATELLITE, HYBRID};
	int mapType = 0;
	String choosen = "";
	
	String typesString = "";
	
	Double passedInLatitude;
	Double passedInLongitude;
	
	boolean dontSet = false;
	
	Double passedInLatitudefriend;
	Double passedInLongitudefriend;
	
	boolean dontSetfriend = false;
	
	static String usernameThatSentTheFriendRequest = "";

	
	//private String[] autoCompleteArray;
	
	int id = 0;

	Double currentLatitudeOfCurrentUser = 0.1;
	Double currentLongitudeOfCurrentUser = 0.1;

	Double lastLatitudeOfCurrentUser = 0.0;
	Double lastLongitudeOfCurrentUser = 0.0;

	

	private final static int INTERVAL = 10000; // 10 Seconds
	Handler m_handler = new Handler();

	Runnable m_handlerTask = new Runnable() {
		@Override
		public void run() {
			checkRequest();
			if (gMap != null)
			{
				LatLng x = gMap.getCameraPosition().target;
				currentLatitudeOfCurrentUser = x.latitude;
				currentLongitudeOfCurrentUser = x.longitude;
			}
			if (lastLatitudeOfCurrentUser != currentLatitudeOfCurrentUser
					&& lastLongitudeOfCurrentUser != currentLongitudeOfCurrentUser) {
				lastLatitudeOfCurrentUser = currentLatitudeOfCurrentUser;
				lastLongitudeOfCurrentUser = currentLongitudeOfCurrentUser;
				Log.d("HERE","HERETHO");
				updateLocation(currentLatitudeOfCurrentUser,
						currentLongitudeOfCurrentUser);
			}
			m_handler.postDelayed(m_handlerTask, INTERVAL);
		}

		private void updateLocation(Double lat, Double lon) {
			
			Double[] temp = new Double[2];
			temp[0] = lat;
			temp[1] = lon;

			new updateLocation().execute(temp);
			new saveFavorite().execute(new String[] {"",""+lat,""+lon});

		}
	};

	private MapFragment mapFrag;

	private Context mainContext;

	private GoogleMap gMap;

	private AutoCompleteTextView etEnterLocation;

	private LatLng latLng;

	private MarkerOptions markerOptions;

	private double[] currentBounds;

	private LocationManager locMan;
	
	private ArrayAdapter<String> adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mainContext = this;
		getActionBar().setDisplayShowTitleEnabled(false);
		passedInLatitude = -1.0;
		passedInLongitude = -1.0;
		passedInLatitudefriend = -1.0;
		passedInLongitudefriend = -1.0;

		startRepeatingTask();
		
		Intent intent = getIntent();
		if(intent.getStringExtra("lat") != null && intent.getStringExtra("lon") != null)
		{
			passedInLatitude = Double.parseDouble(intent.getStringExtra("lat"));
			passedInLongitude = Double.parseDouble(intent.getStringExtra("lon"));
			dontSet=true;
		}
		
		if(intent.getStringExtra("latf") != null && intent.getStringExtra("lonf") != null)
		{
			passedInLatitudefriend = Double.parseDouble(intent.getStringExtra("latf"));
			passedInLongitudefriend = Double.parseDouble(intent.getStringExtra("lonf"));
			dontSetfriend=true;
		}
		Log.d("here", passedInLatitudefriend+"");

		// Setting the map fragment
		mapFrag = (MapFragment) getFragmentManager().findFragmentById(
				R.id.mapView);
		// initializing the map
		gMap = mapFrag.getMap();
		// setting the map to a normal (i.e. map) view
		gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
		// enabling location layer of the google map
		gMap.setMyLocationEnabled(true);
		
		gMap.setOnMapLongClickListener(this);
		
		
		//Alows you to click on the info
		gMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

            public void onInfoWindowClick(Marker marker) {

            	double lat = marker.getPosition().latitude;
        		double lon = marker.getPosition().longitude;
        		
        		
        		Intent i = new Intent(mainContext, Favorite.class);
        		i.putExtra("lat", lat+"");
        		i.putExtra("lon", lon+""); 
        		startActivity(i);



            }
    });
		
		gMap.setOnMarkerDragListener(new OnMarkerDragListener() {

			@Override
			public void onMarkerDrag(Marker marker) {

				
			}

			@Override
			public void onMarkerDragEnd(Marker marker) {

				
			}

			@Override
			public void onMarkerDragStart(Marker marker) {
				// TODO Auto-generated method stub
				
			}
        });

		



		// setting listener for EditText on main page when user clicks "Go" on
		// the keyboard
		etEnterLocation = (AutoCompleteTextView) findViewById(R.id.et_enter_location);
		etEnterLocation
				.setOnEditorActionListener(new TextView.OnEditorActionListener() {
					@Override
					public boolean onEditorAction(TextView v, int actionId,
							KeyEvent event) {
						if (actionId == EditorInfo.IME_ACTION_GO) {
							
							/*String loc = etEnterLocation.getText().toString();
							if (loc != null && !loc.equals("")) {
								VisibleRegion boundaries = gMap.getProjection()
										.getVisibleRegion();
								LatLngBounds latlngBounds = boundaries.latLngBounds;
								LatLng ne = latlngBounds.northeast;
								LatLng sw = latlngBounds.southwest;
								currentBounds = new double[] { sw.latitude,
										sw.longitude, ne.latitude, ne.longitude };
								new FindByGeocoderTask().execute(loc);
							}*/
							new SearchTask().execute(v.getText().toString());
							InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
							imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
							return true;
						}
						return false;
					}
				});

		locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		LocationListener locLis = new LocationListener() {
			@Override
			public void onLocationChanged(Location location) {
				if(!dontSet && !dontSetfriend)
				{
				
					gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
							new LatLng(location.getLatitude(), location
									.getLongitude()), 10));
				}

				currentLatitudeOfCurrentUser = location.getLatitude();
				currentLongitudeOfCurrentUser = location.getLongitude();

			}

			@Override
			public void onProviderDisabled(String provider) {
			}

			@Override
			public void onProviderEnabled(String provider) {
			}

			@Override
			public void onStatusChanged(String provider, int status,
					Bundle extras) {
			}
		};

		locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 400,
				1000, locLis);
		
		
		adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
		adapter.setNotifyOnChange(true);
		etEnterLocation.setAdapter(adapter);

		
		etEnterLocation.addTextChangedListener(new TextWatcher()
		{
			
			@Override
			public void afterTextChanged(Editable arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count)
			{				
				if (count%3 == 1)
				{
					adapter.clear();
					
					new AutoCompleteTask().execute(s.toString());
				}
			}
		});

		if(passedInLatitude != -1.0 && passedInLongitude != -1.0)
		{
			gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
					new LatLng(passedInLatitude, passedInLongitude), 10));
		}

		Log.d("speghettios", passedInLongitudefriend+"");
		if(passedInLatitudefriend != -1.0 && passedInLongitudefriend != -1.0)
		{
			System.out.println("here we areeeee");
			gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
					new LatLng(passedInLatitudefriend, passedInLongitudefriend), 10));
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.logout) {
			DatabaseHandler dbh = new DatabaseHandler(this);
			dbh.logoutCurrentUser();
			dbh.close();
			this.finish();
			Intent login = new Intent(this, Login.class);
			startActivity(login);
			return true;
		} else if (item.getItemId() == R.id.friend) {
			Intent friend = new Intent(this, Newfriend.class);
			startActivity(friend);
			return true;
		}else if (item.getItemId() == R.id.favorites) {
			Intent friend = new Intent(this, FavoriteList.class);
			startActivity(friend);
			return true;
		}else if (item.getItemId() == R.id.filter)
		{
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
		    builder.setTitle("Choose Places to Search");
		    builder.setMultiChoiceItems(types, states, new DialogInterface.OnMultiChoiceClickListener(){
		        public void onClick(DialogInterface dialogInterface, int item, boolean state) {
		        }
		    });
		    
		    
		    builder.setPositiveButton("Okay", new DialogInterface.OnClickListener()
		    {
		        public void onClick(DialogInterface dialog, int id)
		        {
		            typesString = "";
		        	SparseBooleanArray CheCked = ((AlertDialog) dialog).getListView().getCheckedItemPositions();
		            if (CheCked.get(0))
		            {
		            	typesString += "airport|";
		            }
		            if (CheCked.get(1))
		            {
		            	typesString += "atm|bank|";
		            }
		            if (CheCked.get(2))
		            {
		            	typesString += "bar|";
		            }
		            if (CheCked.get(3))
		            {
		            	typesString += "car_repair|";
		            }
		            if (CheCked.get(4))
		            {
		            	typesString += "dentist|doctor|hospital|";
		            }
		            if (CheCked.get(5))
		            {
		            	typesString += "food|";
		            }
		            if (CheCked.get(6))
		            {
		            	typesString += "gas_station|car_wash|";
		            }
		            if (CheCked.get(7))
		            {
		            	typesString += "gym|";
		            }
		            if (CheCked.get(8))
		            {
		            	typesString += "locksmith|";
		            }
		            if (CheCked.get(9))
		            {
		            	typesString += "lodging|";
		            }
		            if (CheCked.get(10))
		            {
		            	typesString += "movie_theater|aquarium|bowling_alley|casino|museum|stadium|zoo|";
		            }
		            if (CheCked.get(11))
		            {
		            	typesString += "park|";
		            }
		            if (CheCked.get(12))
		            {
		            	typesString += "parking|";
		            }
		            if (CheCked.get(13))
		            {
		            	typesString += "place_of_worship|";
		            }
		            if (CheCked.get(14))
		            {
		            	typesString += "post_office|";
		            }
		            if (CheCked.get(15))
		            {
		            	typesString += "store|pharmacy|";
		            }
		        }
		    });
		    
			
		    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int id) {
		             dialog.cancel();
		        }
		    });
		    builder.create().show();
			return true;
		}
		else if (item.getItemId() == R.id.update)
		{
			
			String[] temp = new String[3];
			LatLng x = gMap.getCameraPosition().target;
			currentLatitudeOfCurrentUser = x.latitude;
			currentLongitudeOfCurrentUser = x.longitude;
			temp[0] = "";
			temp[1] = ""+currentLatitudeOfCurrentUser;
			temp[2] = ""+currentLongitudeOfCurrentUser;
			
			new saveFavorite().execute(temp);
			
			
			
			//Intent update = new Intent(this, UpdateLocation.class);
			//startActivity(update);
			return true;
		}
		else if (item.getItemId() == R.id.map_type)
		{
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
		    builder.setTitle("Choose a Map Type");
		    builder.setSingleChoiceItems(mapTypes, mapType, new DialogInterface.OnClickListener()
		    {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					choosen = mapTypes[which].toString();
				}
		    }).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
		    {
		    	
		    	public void onClick(DialogInterface dialog, int id)
		    	{
		    		mapType = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
		    		switch(mapType)
		    		{
		    		case 0:
		    			if (gMap.getMapType() != GoogleMap.MAP_TYPE_NORMAL)
		    			{
		    				gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
		    			}
		    			break;
		    		case 1:
		    			if (gMap.getMapType() != GoogleMap.MAP_TYPE_SATELLITE)
		    			{
		    				gMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
		    			}
		    			break;
		    		case 2:
		    			if (gMap.getMapType() != GoogleMap.MAP_TYPE_HYBRID)
		    			{
		    				gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
		    			}
		    			break;
		    		default:
		    			break;
		    		}
		    	}
		    }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which)
				{
					dialog.cancel();
				}
			});
		    builder.create().show();
			return true;
		}
		else {
			return super.onOptionsItemSelected(item);
		}
	}
	

	
	
	private class AutoCompleteTask extends AsyncTask<String, Object, String[]>
	{

		@Override
		protected String[] doInBackground(String... params) {
			String[] plArray = null;
			
			String input = params[0];
			input = input.trim();
			input = input.replace(" ","_");
			input = input.replace("'","");
			
			String placesUrl = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" + input + "&location=" +  currentLatitudeOfCurrentUser + "," + currentLongitudeOfCurrentUser + "&radius=10000&sensor=false&key=AIzaSyDSWaH1Rt9qUwpMxJjUgULbhpju0C4U6Jc";
			
			try {
				URL googlePlaces = new URL(placesUrl);
				URLConnection tc = googlePlaces.openConnection();
				BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
				String line;
				StringBuffer sb = new StringBuffer();
				while((line = in.readLine()) != null)
				{
					sb.append(line);
				}
				JSONObject predictions = new JSONObject(sb.toString());
				JSONArray ja = new JSONArray(predictions.getString("predictions"));
				
				plArray = new String[ja.length()];
				
				for (int i = 0; i < ja.length(); i++)
				{
					JSONObject jo = (JSONObject)ja.get(i);
					plArray[i] = jo.getString("description");
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			return plArray;
		}
		
		@Override
		protected void onPostExecute(String[] plArray)
		{

			adapter.addAll(plArray);
		}
		
	}
	
	public void checkRequest() {

		new checkFriendRequests().execute(getApplicationContext());
	}

	public class checkFriendRequests extends
			AsyncTask<Context, Context, String> {

		@Override
		protected String doInBackground(Context... params) {

			int userNum = Login.currentUserId;
			String response = "";

			HttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(
					"http://softeng.cs.uwosh.edu/students/cs342g6/checkRequest.php?user_id="
							+ userNum);
			try {

				// Execute HTTP Post Request

				ResponseHandler<String> responseHandler = new BasicResponseHandler();
				response = httpclient.execute(httppost, responseHandler);
				response = response.trim();

				if (!response.equals("none")) {
					
					

					usernameThatSentTheFriendRequest = response;


					return usernameThatSentTheFriendRequest;
				}

			} catch (ClientProtocolException e) {
			} catch (IOException e) {
			}
			return null;
		}

		@Override
		protected void onPostExecute(String values) {

			if (values != null) {


				String ns = Context.NOTIFICATION_SERVICE;
				NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

				int icon = R.drawable.ic_launcher;
				CharSequence tickerText = "You Have a new friend request!";
				long when = System.currentTimeMillis();

				Notification notification = new Notification(icon, tickerText,
						when);

				Context context = getApplicationContext();
				CharSequence contentTitle = "Map App";
				CharSequence contentText = "You Have a new friend request!";
				Intent notificationIntent = new Intent(mainContext,
						Friendrequest.class);
				notificationIntent.putExtra("name",
						values);
				Log.d(values,"IAMHERE1");
				PendingIntent contentIntent = PendingIntent.getActivity(mainContext,
						0, notificationIntent, 0);

				notification.setLatestEventInfo(context, contentTitle,
						contentText, contentIntent);

				id++;
				notification.flags = Notification.FLAG_INSISTENT
						| Notification.FLAG_AUTO_CANCEL;

				mNotificationManager.notify(id, notification);
 
			}

		}
	}

	public class updateLocation extends
			AsyncTask<Double, Boolean, Boolean> {

		@Override
		protected Boolean doInBackground(Double... params) {
			
			ArrayList<NameValuePair> postParameters;
			
			postParameters = new ArrayList<NameValuePair>();
			

			postParameters.add(new BasicNameValuePair("latitude",params[0]+""));
			postParameters.add(new BasicNameValuePair("longitude",params[1]+""));
			postParameters.add(new BasicNameValuePair("id",Login.currentUserId+""));

			HttpClient httpclient = new DefaultHttpClient();
		    HttpPost httppost = new HttpPost("http://softeng.cs.uwosh.edu/students/cs342g6/updateLocation.php");
		    try {
				httppost.setEntity(new UrlEncodedFormEntity(postParameters));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		    

		    try {

		        // Execute HTTP Post Request

		        ResponseHandler<String> responseHandler = new BasicResponseHandler();
		        String response = httpclient.execute(httppost, responseHandler).trim();
		        
		        if(Integer.parseInt(response) == 1)
		        {
		        	return true;
		        }
		        else
		        {
		        	return false;
		        }
		        
		    } catch (ClientProtocolException e) {
		        //Toast.makeText(params[0], "CPE response " + e.toString(), Toast.LENGTH_LONG).show();
		        // TODO Auto-generated catch block
		    } catch (IOException e) {
		        //Toast.makeText(params[0], "IOE response " + e.toString(), Toast.LENGTH_LONG).show();
		        // TODO Auto-generated catch block
		    }
			return false;

		}
		    


		@Override
		protected void onPostExecute(Boolean values) {

			
		}
	}
	
	
	
	
	private class SearchTask extends AsyncTask<String, Double[], String[]>
	{

		@Override
		protected String[] doInBackground(String... params)
		{
			String input = params[0];
			//input = input.replace(" ", "%22");
			
			String placesUrl = "https://maps.googleapis.com/maps/api/place/search/json?";
			String placesQuery = "name=" + input +
					(typesString.equals("") ? "" : "&types=" +  typesString.substring(0, typesString.length()-1)) +
					"&location=" +  currentLatitudeOfCurrentUser + "," + currentLongitudeOfCurrentUser + 
					"&radius=20000&sensor=false&key=AIzaSyDSWaH1Rt9qUwpMxJjUgULbhpju0C4U6Jc";
			
			try
			{
				URI uri = new URI(
						"https",
						"maps.googleapis.com",
						"/maps/api/place/search/json",
						placesQuery,
						null
						);
				String placeReq = uri.toASCIIString();
				placeReq = placeReq.replace("%20", "%22");
				
				
				
				System.out.println(placeReq);
				URL googlePlaces = new URL(placeReq);
				URLConnection tc = googlePlaces.openConnection();
				BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
				String line;
				StringBuffer sb = new StringBuffer();
				while((line = in.readLine()) != null)
				{
					sb.append(line);
				}
				// this is the JSON object for the entire places search.
				JSONObject joSearchResults = new JSONObject(sb.toString());
				JSONArray jaSearchResults = new JSONArray(joSearchResults.getString("results"));
				String[] references = new String[jaSearchResults.length()];
				for(int i = 0; i < jaSearchResults.length(); i++)
				{
					JSONObject jo = jaSearchResults.getJSONObject(i);
					references[i] = jo.getString("reference");
				}
				return references;
			}
			catch(Exception e)
			{
				System.out.println("Error during Google Places Search");
			}
			
			return null;
		}
		
		
		@Override
		protected void onPostExecute(String[] refArray)
		{
			if (refArray != null)new ProcessSearchResultsTask().execute(refArray);
		}
	}
	
	/**
	 * Take in an array of references
	 * Build SearchResult Objects through calls to google places details search.
	 * @author Ryan
	 *
	 */
	private class ProcessSearchResultsTask extends AsyncTask<String[], Object, SearchResult[]>
	{
		@Override
		protected SearchResult[] doInBackground(String[]... params) {
			SearchResult[] searchResults = new SearchResult[params[0].length];
			String placesUrl = "https://maps.googleapis.com/maps/api/place/details/json?";
			String key = "AIzaSyDSWaH1Rt9qUwpMxJjUgULbhpju0C4U6Jc";
			try
			{
				for(int i = 0; i < params[0].length; i++)
				{
					URL googlePlaces = new URL(placesUrl + "reference=" + params[0][i] + "&sensor=false&key=" + key);
					URLConnection tc = googlePlaces.openConnection();
					BufferedReader in = new BufferedReader(new InputStreamReader(tc.getInputStream()));
					String line;
					StringBuffer sb = new StringBuffer();
					while((line = in.readLine()) != null)
					{
						sb.append(line);
					}
					JSONObject detailsResponse = new JSONObject(sb.toString());
					JSONObject result = detailsResponse.getJSONObject("result");
					searchResults[i] = new SearchResult(result);
				}
				return searchResults;
			}
			catch(Exception e)
			{
				
			}
			
			return null;
		}
		
		@Override
		protected void onPostExecute(SearchResult[] searchResults)
		{
			if (searchResults != null) new PlaceMarkersTask().execute(searchResults);
		}
	}
	
	/**
	 * Takes an array of SearchResults and places the markers on the map in the indicated places.
	 * Will animate the camera to the first result post execute.
	 * @author Ryan
	 *
	 */
	private class PlaceMarkersTask extends AsyncTask<SearchResult[], Object, Object[]>
	{

		@Override
		protected Object[] doInBackground(SearchResult[]... params)
		{
			double min = Double.MAX_VALUE;
			LatLng minLL = null;
			Object[] retArray = new Object[params[0].length+1];
			for(int i = 0; i < params[0].length; i++)
			{
				double potentialMin = distance(currentLatitudeOfCurrentUser,currentLongitudeOfCurrentUser,params[0][i].latitude,params[0][i].longitude);
				if (potentialMin < min)
				{
					min = potentialMin;
					minLL = new LatLng(params[0][i].latitude,params[0][i].longitude);
				}
				MarkerOptions mo = new MarkerOptions();
				mo.position(new LatLng(params[0][i].latitude,params[0][i].longitude));
				mo.title(params[0][i].name);
				mo.snippet( "Phone: " + params[0][i].phone + ":;:" + params[0][i].address + ":;:" + params[0][i].icon);
				try {
					URL url = new URL(params[0][i].icon);
					mo.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeStream(url.openConnection().getInputStream())));
				} catch (Exception e) {
				}
				
				//mo.icon(BitmapDescriptorFactory.)
				retArray[i] = mo;
				
			}
			retArray[retArray.length-1] = minLL;
			//return new LatLng(params[0][0].latitude,params[0][0].longitude);
			return retArray;
		}
		
		@Override
		protected void onPostExecute(Object[] result)
		{
			
			gMap.setInfoWindowAdapter(new InfoWindowAdapter()
			{
				final View contents = getLayoutInflater().inflate(R.layout.info_window_content, null);
				
				@Override
				public View getInfoContents(Marker marker) {
					
					String title = marker.getTitle();
					TextView tvTitle = (TextView)contents.findViewById(R.id.infoWindowTitle);
					if (title != null)
					{
						tvTitle.setText(title);
					}
					else
					{
						tvTitle.setText("");
					}
					String snip = marker.getSnippet();
					String[] info = null;
					if (snip != null)
					{
						info = snip.split(":;:");
					}
					TextView phone = (TextView)contents.findViewById(R.id.infoWindowPhone);
					if (info[0] != null)
					{
						phone.setText(info[0]);
					}
					else
					{
						phone.setText("");
					}
					TextView address = (TextView)contents.findViewById(R.id.infoWindowAddress);
					if (info[1] != null)
					{
						address.setText(info[1]);
					}
					else
					{
						address.setText("");
					}
					ImageView ivIcon = (ImageView)contents.findViewById(R.id.infoWindowIcon);
					
					if (info[2] != null)
					{
						Bitmap ic = null;
						try {
							ic = new GetBitmapFromURLTask().execute(info[2]).get();
						} catch (Exception e) {
						}
						if (ic != null){
							ivIcon.setImageBitmap(ic);
						}
					}
					
					return contents;
				}

				@Override
				public View getInfoWindow(Marker marker) {
					
					return null;
				}
				
			});
			gMap.clear();
			for (int i = 0; i < result.length-1; i++)
			{
				gMap.addMarker((MarkerOptions)result[i]);
			}
			
			if (result[result.length-1] != null) gMap.animateCamera(CameraUpdateFactory.newLatLngZoom((LatLng)result[result.length-1], 15));
		}
	}
	/*
	 * Distance formula helper
	 */
	private double distance(double currentLat, double currentLng, double destinationLat, double destinationLng)
	{
		return Math.sqrt(Math.pow((destinationLng - currentLng),2) + Math.pow((destinationLat-currentLat),2));
	}
	
	
	private class GetBitmapFromURLTask extends AsyncTask<String,Object,Bitmap>
	{
		@Override
		protected Bitmap doInBackground(String... params) {
			Bitmap bmp = null;
			try {
				URL url = new URL(params[0]);
				bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
			} catch (Exception e) {
			}
			return bmp;
		}
	}
	

	private class FindByGeocoderTask extends
			AsyncTask<String, Double[], List<Address>> {

		@Override
		protected List<Address> doInBackground(String... arg0) {
			Geocoder geo = new Geocoder(getBaseContext());
			List<Address> addresses = null;

			try {
				addresses = geo.getFromLocationName(arg0[0], 5,
						currentBounds[0], currentBounds[1], currentBounds[2],
						currentBounds[3]);
			} catch (Exception e) {
				Toast.makeText(getBaseContext(), "Error: do in background",
						Toast.LENGTH_SHORT).show();
			}

			return addresses;
		}

		protected void onPostExecute(List<Address> addresses) {
			if (addresses == null || addresses.isEmpty()) {
				Toast.makeText(getBaseContext(), "Error: no location found",
						Toast.LENGTH_SHORT).show();
			}
 
			gMap.clear();
			System.out.println("Starting Address Printing");
			for (int i = 0; i < addresses.size(); i++) {
				Address address = (Address) addresses.get(i);
				System.out.println("Adress " + i + " = " + address);
				latLng = new LatLng(address.getLatitude(),
						address.getLongitude());

				String addressText = String.format(
						"%s, %s",
						address.getMaxAddressLineIndex() > 0 ? address
								.getAddressLine(0) : "", address
								.getCountryName());

				markerOptions = new MarkerOptions();
				markerOptions.position(latLng);
				markerOptions.title(addressText);

				gMap.addMarker(markerOptions);

				if (i == 0) {
					gMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
				}

			}
		}
	}
	
	
	
	public class saveFavorite extends AsyncTask<String, Context, String> {

		@Override
		protected String doInBackground(String... params) {

			String name = params[0];
			Double lat = Double.parseDouble(params[1]);
			Double lon = Double.parseDouble(params[2]);
			
			ArrayList<NameValuePair> postParameters;
			
			postParameters = new ArrayList<NameValuePair>();
			

			postParameters.add(new BasicNameValuePair("latitude",lat+""));
			postParameters.add(new BasicNameValuePair("longitude",lon+""));
			postParameters.add(new BasicNameValuePair("id",Login.currentUserId+""));
			postParameters.add(new BasicNameValuePair("name",name));



			HttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(
					"http://softeng.cs.uwosh.edu/students/cs342g6/saveFavoriteManual.php");
			try {
				httppost.setEntity(new UrlEncodedFormEntity(postParameters));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

		    try {

		        // Execute HTTP Post Request

		        ResponseHandler<String> responseHandler = new BasicResponseHandler();
		        String response = httpclient.execute(httppost, responseHandler).trim();
		        
		        if(Integer.parseInt(response) == 1)
		        {
		        	return "true";
		        }
		        else
		        {
		        	return "false";
		        }
		        
		    } catch (ClientProtocolException e) {
		        //Toast.makeText(params[0], "CPE response " + e.toString(), Toast.LENGTH_LONG).show();
		        // TODO Auto-generated catch block
		    } catch (IOException e) {
		        //Toast.makeText(params[0], "IOE response " + e.toString(), Toast.LENGTH_LONG).show();
		        // TODO Auto-generated catch block
		    }
			return "false";
		    

		}

		@Override
		protected void onPostExecute(String values) {

			if(values.equals("true"))
			{
				//Toast.makeText(getApplicationContext(), "Location Updated", Toast.LENGTH_SHORT).show();
			}

		}
	}
	
	
	

	void startRepeatingTask() {
		m_handlerTask.run();
	}

	void stopRepeatingTask() {
		m_handler.removeCallbacks(m_handlerTask);
	}

	@Override
	public void onMapClick(LatLng arg0) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void onMapLongClick(LatLng point) {
        // TODO Auto-generated method stub
         gMap.addMarker(new MarkerOptions()
         .position(point).title("Favorite?")           
    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))).setDraggable(true);  
         
         
    }

	
	
	

}